package com.yunxi.service.dubboService.impl.sat;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.yunxi.baseDataToHub.pojo.urm.UrmTestDriveVO;
import com.yunxi.baseDataToHub.service.urm.UrmDubboService;
import com.yunxi.core.web.ApiResult;
import com.yunxi.core.web.DictConstant;
import com.yunxi.core.web.LoginInfo;
import com.yunxi.model.sat.SatConfig;
import com.yunxi.model.sat.SatTestDrive;
import com.yunxi.sat.pojo.*;
import com.yunxi.sat.service.SatTestDriveDubboService;
import com.yunxi.service.localService.sat.*;
import com.yunxi.sys.pojo.StaffVO;
import com.yunxi.sys.service.StaffDubboService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 试乘试驾表 服务实现类
 * </p>
 *
 * @author caoYong
 * @since 2019-07-31
 */
public class SatTestDriveDubboServiceImpl implements SatTestDriveDubboService {
    private static final Logger logger = LoggerFactory.getLogger(SatTestDriveDubboServiceImpl.class);


    @Autowired
    @Qualifier(value = "satTestDriveServiceImpl")
    SatTestDriveService satTestDriveService;

    @Autowired
    @Qualifier(value = "satConfigServiceImpl")
    SatConfigService satConfigService;

    @Autowired
    UrmDubboService urmDubboServiceImplBiz;

    @Autowired
    @Qualifier(value = "satCustomerClueServiceImpl")
    SatCustomerClueService satCustomerClueService;

    @Autowired
    @Qualifier(value = "msgTemplateServiceImpl")
    MsgTemplateService msgTemplateService;

    @Autowired
    @Qualifier(value = "satMessServiceImpl")
    SatMessService satMessService;

    @Autowired
    @Qualifier(value = "staffDubboServiceBiz")
    StaffDubboService staffDubboService;

    @Override
    public SatTestDriveVO getById(String id) throws Exception {
        SatTestDrive satTestDrive = satTestDriveService.getById(id);
        if(satTestDrive == null) throw new Exception("操作失败,无法根据id:"+id+"找到对应试驾记录!");
        SatTestDriveVO satTestDriveVO = new SatTestDriveVO();
        BeanUtils.copyProperties(satTestDrive, satTestDriveVO);
        return satTestDriveVO;
    }

    /**
     * 获取试驾详情
     * @param id
     * @return
     * @throws Exception
     */
    @Override
    public SatTestDriveDetailVO getInfoById(String id) throws Exception {
        return satTestDriveService.getInfoById(id);
    }

    @Override
    public SatTestDriveDetailVO testDriveInfo(String customerNo) throws Exception {
        return satTestDriveService.testDriveInfo(customerNo);
    }

    @Override
    public String saveOrUpdate(SatTestDriveVO satTestDriveVO,LoginInfo loginInfo) throws Exception {
        satTestDriveVO.setPartnerCode(loginInfo.getPartnerCode());
        satTestDriveVO.setCreateBy(loginInfo.getUserCode());
        SatTestDrive satTestDrive = new SatTestDrive();
        BeanUtils.copyProperties(satTestDriveVO, satTestDrive);
        if(satTestDrive.getDriveId() == null){
            satTestDrive.setSalesConsultantNo(loginInfo.getUserCode());
        }
        //校验同一个试驾专家的计划试驾时间是否重复(限制到小时)
        checkPlanTestDriveTime(satTestDriveVO);
        satTestDriveService.saveOrUpdate(satTestDrive);

        //设置URM试乘试驾信息字段
        satTestDriveVO.setSalesConsultantNo(loginInfo.getUserCode());
        UrmTestDriveVO urmTestDriveVO = setTestDriveInfoURM(satTestDriveVO);
        //发送试乘试驾信息到URM
        sendTestDriveInfo2URM(urmTestDriveVO);

        //生成消息给试驾专家
        msgPush(satTestDriveVO, loginInfo);

        return satTestDrive.getDriveId();
    }


    private UrmTestDriveVO setTestDriveInfoURM(SatTestDriveVO satTestDriveVO) {
        SatTestDriveVO salesInfo = satTestDriveService.getSalesInfo(satTestDriveVO.getSalesConsultantNo());
        if(salesInfo != null){
            satTestDriveVO.setSalesConsultantName(salesInfo.getSalesConsultantName());
            satTestDriveVO.setSalesConsultantPhone(salesInfo.getSalesConsultantPhone());
        }
        UrmTestDriveVO urmTestDriveVO = new UrmTestDriveVO();
        if(StringUtils.isNotEmpty(satTestDriveVO.getCustomerNo())){
            urmTestDriveVO.setCustomerNo(satTestDriveVO.getCustomerNo());//客户ID
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getCreateBy())){
            urmTestDriveVO.setSalesConsultantNo(satTestDriveVO.getCreateBy());//销售顾问编号
        }
        urmTestDriveVO.setTestDriveStatus(1);//试驾状态
        if(satTestDriveVO.getDriveStyle() != null){
            urmTestDriveVO.setDriveStyle(satTestDriveVO.getDriveStyle());//试驾方式
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getDriveType())){
            urmTestDriveVO.setDriveType(Integer.parseInt(satTestDriveVO.getDriveType()));//试驾人身份类型
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getPartnerCode())){
            urmTestDriveVO.setPartnerCode(satTestDriveVO.getPartnerCode());//渠道编号
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getCustomerName())){
            urmTestDriveVO.setCustomerName(satTestDriveVO.getCustomerName());//客户姓名
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getTestDriveRouteId())){
            urmTestDriveVO.setTestDriveRouteId(satTestDriveVO.getTestDriveRouteId());//线路信息
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getCertType())){
            urmTestDriveVO.setCertType(Integer.parseInt(satTestDriveVO.getCertType()));//试驾人证件类型
        }
        if(satTestDriveVO.getApplyType() != null){
            urmTestDriveVO.setApplyType(satTestDriveVO.getApplyType());//申请类型
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getCertPicFront())){
            urmTestDriveVO.setCertPicFront(satTestDriveVO.getCertPicFront());//身份证正面
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getCertPicBack())){
            urmTestDriveVO.setCertPicBack(satTestDriveVO.getCertPicBack());//身份证反面
        }
        Date planDriveTime = satTestDriveVO.getPlanDriveTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if(planDriveTime != null){
            String format = simpleDateFormat.format(planDriveTime);
            urmTestDriveVO.setPlanDriveTime(format);//计划试驾时间(存到分钟)
        }
        Date completeDriveTime = satTestDriveVO.getCompleteDriveTime();
        if(completeDriveTime != null){
            String format1 = simpleDateFormat.format(completeDriveTime);
            urmTestDriveVO.setCompleteDriveTime(format1);//完成试驾时间
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getAudi())){
            urmTestDriveVO.setAudi(satTestDriveVO.getAudi());//车系
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getDriveInfo())){
            urmTestDriveVO.setDriveInfo(satTestDriveVO.getDriveInfo());//试驾员描述
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getMemo())){
            urmTestDriveVO.setMemo(satTestDriveVO.getMemo());//试驾备注
        }

        urmTestDriveVO.setIsGet(satTestDriveVO.getIsGet());//是否领取1领取0未领取
        urmTestDriveVO.setGetUser(satTestDriveVO.getSalesConsultantNo());//领取人
//        urmTestDriveVO.setStatus(satTestDriveVO.getStatus());//状态1启用0禁用
        Integer isDel = satTestDriveVO.getIsDel();
        if(isDel != null){
            urmTestDriveVO.setIsDel(isDel.toString());//是否删除
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getTestDriveExpert())){
            urmTestDriveVO.setTestDriveExpert(satTestDriveVO.getTestDriveExpert());//试驾专家
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getAgreementPicPath())){
            urmTestDriveVO.setAgreementPicPath(satTestDriveVO.getAgreementPicPath());//试驾协议照片地址
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getCancelReason())){
            urmTestDriveVO.setCancelReason(satTestDriveVO.getCancelReason());//取消原因
        }

        Date beginDriveTime = satTestDriveVO.getBeginDriveTime();
        if(beginDriveTime != null){
            String format2 = simpleDateFormat.format(beginDriveTime);
            urmTestDriveVO.setBeginDriveTime(format2);//开始试驾时间
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getSalesConsultantName())){
            urmTestDriveVO.setSalesConsultantName(satTestDriveVO.getSalesConsultantName());//销售顾问姓名
        }
        if(StringUtils.isNotEmpty(satTestDriveVO.getSalesConsultantPhone())){
            urmTestDriveVO.setSalesConsultantMobile(satTestDriveVO.getSalesConsultantPhone());//销售顾问电话
        }
        return urmTestDriveVO;
    }

    private ApiResult sendTestDriveInfo2URM(UrmTestDriveVO urmTestDriveVO) throws Exception {
        ApiResult apiResult = null;
        try {
             apiResult = urmDubboServiceImplBiz.sendUrmTestDrivePMS2Urm(urmTestDriveVO);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
        }
        if (200 != apiResult.getCode()) {
            logger.error("URM接口执行，同步试乘试驾信息失败，事务回滚!");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new Exception( "URM接口执行，同步试乘试驾信息失败");
        }
        if (apiResult.getData()!=null ){
            JSON.parseObject((String) apiResult.getData());
        }
        return apiResult;
    }

    @Override
    public void removeById(String id) {
        satTestDriveService.removeById(id);
    }

    @Override
    public PageInfo<SatTestDriveVO> findPageByVO(SatTestDriveVO satTestDriveVO, Integer pageNum, Integer pageSize, LoginInfo loginInfo) throws Exception {
        String roleCode = loginInfo.getRoleCode();
        if(StringUtils.isNotEmpty(roleCode) && roleCode.equals(DictConstant.USER_ROLE_TESTDRIVE)){
            satTestDriveVO.setTestDriveExpert(loginInfo.getUserCode());
        }
        //销售顾问
        if(StringUtils.isNotEmpty(roleCode) && roleCode.equals(DictConstant.USER_ROLE_SALES)){
            satTestDriveVO.setSalesConsultantNo(loginInfo.getUserCode());
        }
        satTestDriveVO.setPartnerCode(loginInfo.getPartnerCode());
        PageInfo<SatTestDriveVO> pageInfo = satTestDriveService.pageByVo(satTestDriveVO, pageNum, pageSize);
        return pageInfo;
    }

    @Override
    public void removeByListVo(List<SatTestDriveVO> satTestDriveVOList) throws Exception {
        satTestDriveService.removeByListVo(satTestDriveVOList);
    }

    @Override
    public List listByVo(SatTestDriveVO satTestDriveVO,LoginInfo loginInfo) {
        satTestDriveVO.setPartnerCode(loginInfo.getPartnerCode());
        return satTestDriveService.listByVo(satTestDriveVO);
    }

    /**
     * 获取试驾协议
     * @param partnerCode
     * @return
     * @throws Exception
     */
    @Override
    public String aggreeMent(String partnerCode) throws Exception {
        if(StringUtils.isEmpty(partnerCode))throw new Exception("操作失败,渠道商代码为空!");
        QueryWrapper<SatConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("PARTNER_CODE",partnerCode);
        List<SatConfig> list = satConfigService.list(queryWrapper);
        if(list != null && list.size() > 0){
            return list.get(0).getDriveInfo();
        }
        else {
            throw new Exception("操作失败,无法根据渠道商代码:"+partnerCode+"找到对应试驾协议!");
        }
    }

    /**
     * 取消试驾
     * @param satTestDriveCancelVO
     * @throws Exception
     */
    @Override
    public void cancelTestDrive(SatTestDriveCancelVO satTestDriveCancelVO) throws Exception {
        String driveId = satTestDriveCancelVO.getDriveId();
        SatTestDrive satTestDrive = satTestDriveService.getById(driveId);
        if(satTestDrive == null)throw new Exception("操作失败,无法根据主键:"+driveId+"找到试驾记录!");
        satTestDrive.setTestDriveStatus(3);
        satTestDrive.setCancelReason(satTestDriveCancelVO.getCancelReason());
        satTestDriveService.saveOrUpdate(satTestDrive);
    }

    /**
     * 完成试驾
     * @param satTestDriveCompletelVO
     * @throws Exception
     */
    @Override
    public void complete(SatTestDriveCompletelVO satTestDriveCompletelVO,String roleCode) throws Exception {
        String driveId = satTestDriveCompletelVO.getDriveId();
        SatTestDrive satTestDrive = satTestDriveService.getById(driveId);
        if(satTestDrive == null)throw new Exception("操作失败,无法根据主键:"+driveId+"找到试驾记录!");
        satTestDrive.setTestDriveStatus(3);
        satTestDrive.setCompleteDriveTime(new Date());
        satTestDrive.setDriveInfo(satTestDriveCompletelVO.getDriveInfo());
        satTestDriveService.saveOrUpdate(satTestDrive);
        //生成消息给销售顾问
        SatMessAddVO satMessAddVO = new SatMessAddVO();
        satMessAddVO.setType("22");
        satMessAddVO.setTemplateType(19);
        satMessAddVO.setCustomerName(satTestDrive.getCustomerName());
        satMessAddVO.setCustomerNo(satTestDrive.getCustomerNo());
        satMessAddVO.setSalesConsultantNo(satTestDrive.getSalesConsultantNo());
        satMessAddVO.setReceiveRoleCode("rolePartnerSale");
        satMessAddVO.setOperaRoleCode(roleCode);
        satMessAddVO.setBusinessKey(satTestDrive.getDriveId());
        satMessService.newMess(satMessAddVO);
    }

    /**
     * 开始试驾
     * @param satTestDriveCompletelVO
     * @throws Exception
     */
    @Override
    public void begin(SatTestDriveCompletelVO satTestDriveCompletelVO) throws Exception {
        String driveId = satTestDriveCompletelVO.getDriveId();
        SatTestDrive satTestDrive = satTestDriveService.getById(driveId);
        if(satTestDrive == null)throw new Exception("操作失败,无法根据主键:"+driveId+"找到试驾记录!");
        satTestDrive.setTestDriveStatus(2);
        satTestDrive.setPlanDriveTime(satTestDriveCompletelVO.getPlanDriveTime());
        satTestDrive.setBeginDriveTime(new Date());
        satTestDriveService.saveOrUpdate(satTestDrive);
    }

    /**
     * 本月新增试驾
     * @param satTestDriveCompletelVO
     * @param loginInfo
     * @return
     * @throws Exception
     */
    @Override
    public List<SatTestDriveDetailVO> allList(SatTestDriveCompletelVO satTestDriveCompletelVO, LoginInfo loginInfo) throws Exception {
        Object staff = loginInfo.getStaff();
        String positionCode = null;
        if(staff != null){
            StaffVO staffVO = JSONObject.parseObject(JSONObject.toJSONString(staff), StaffVO.class);
            positionCode = staffVO.getPositionCode();
        }
        satTestDriveCompletelVO.setCompleteDriveTime(new Date());
        satTestDriveCompletelVO.setPartnerCode(loginInfo.getPartnerCode());
        // 非总经理、非销售经理则按登录账号查询
        if (StringUtils.isNotEmpty(loginInfo.getRoleCode()) && !DictConstant.USER_ROLE_MANAGER
            .equals(loginInfo.getRoleCode()) && !DictConstant.USER_ROLE_PARTNER_MANAGER
            .equals(loginInfo.getRoleCode())) {
            satTestDriveCompletelVO.setSalesConsultantNo(loginInfo.getUserCode());
        }
        return satTestDriveService.allList(satTestDriveCompletelVO);
    }

    /**
     * 查询试驾专家待试驾时间列表
     * @param testDriveExpert
     * @param partnerCode
     * @return
     */
    @Override
    public List<Date> testDriveDate(String testDriveExpert, String partnerCode) {
        QueryWrapper<SatTestDrive> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("TEST_DRIVE_EXPERT",testDriveExpert);
        queryWrapper.ne("TEST_DRIVE_STATUS",3);
        queryWrapper.ne("TEST_DRIVE_STATUS",4);
        List<SatTestDrive> list = satTestDriveService.list(queryWrapper);
        List<Date> list1 = new ArrayList<>();
        if(list != null && list.size() > 0){
            for (SatTestDrive bo : list){
                list1.add(bo.getPlanDriveTime());
            }
        }
        return list1;
    }

    /**
     * 更改试驾时间
     * @param satTestDriveCancelVO
     * @throws Exception
     */
    @Override
    public void editDriveTime(SatTestDriveCancelVO satTestDriveCancelVO) throws Exception {
        SatTestDrive testDrive = satTestDriveService.getById(satTestDriveCancelVO.getDriveId());
        if(testDrive == null)throw new Exception("操作失败,无法根据主键:"+satTestDriveCancelVO.getDriveId()+"找到对应记录!");
        testDrive.setPlanDriveTime(satTestDriveCancelVO.getPlanDriveTime());
        SatTestDriveVO satTestDriveVO = new SatTestDriveVO();
        satTestDriveVO.setDriveId(satTestDriveCancelVO.getDriveId());
        satTestDriveVO.setPlanDriveTime(satTestDriveCancelVO.getPlanDriveTime());
        //校验计划试驾时间是否重复
        checkPlanTestDriveTime(satTestDriveVO);
        satTestDriveService.saveOrUpdate(testDrive);
    }

    /**
     * 推送试驾信息到URM
     * @param satTestDriveVO
     * @throws Exception
     */
    @Override
    public void pushTestDriveToURM(SatTestDriveVO satTestDriveVO) throws Exception {
        //设置URM试乘试驾信息字段
        UrmTestDriveVO urmTestDriveVO = setTestDriveInfoURM(satTestDriveVO);
        //发送试乘试驾信息到URM
        sendTestDriveInfo2URM(urmTestDriveVO);
    }

    /**
     * 校验计划试驾时间是否重复
     * @param satTestDriveVO
     * @throws Exception
     */
    private void checkPlanTestDriveTime(SatTestDriveVO satTestDriveVO) throws Exception {
        Integer testDriveCount = satTestDriveService.checkPlanTestDriveTime(satTestDriveVO);
        Date planDriveTime = satTestDriveVO.getPlanDriveTime();
        if(planDriveTime == null)throw new Exception("操作失败,计划试驾时间为空!");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH");
        String format = simpleDateFormat.format(planDriveTime);
        if(testDriveCount > 0){
            throw new Exception("操作失败,该试驾专家于:"+format+"已存在试驾计划!");
        }
    }

    /**
     * 生成消息
     * @param satTestDriveVO
     * @param loginInfo
     */
    private void msgPush(SatTestDriveVO satTestDriveVO, LoginInfo loginInfo) throws InvocationTargetException, IllegalAccessException {
        ApiResult rolePartnerTestDrive = staffDubboService.listStaffByRoleCode("rolePartnerTestDrive", loginInfo);
        SatCustomerClueVO satCustomerClueVO = new SatCustomerClueVO();
        satCustomerClueVO.setCustomerNo(satTestDriveVO.getCustomerNo());
        satCustomerClueVO.setPartnerCode(loginInfo.getPartnerCode());
        String customerName = satCustomerClueService.getCustomerNameByNo(satCustomerClueVO);
        List<StaffVO> list = (List<StaffVO>)rolePartnerTestDrive.getData();
        if(list != null && list.size() > 0){
            for(StaffVO vo : list){

                SatMessAddVO satMessAddVO = new SatMessAddVO();
                satMessAddVO.setType("21");
                satMessAddVO.setTemplateType(18);
                satMessAddVO.setCustomerName(customerName);
                satMessAddVO.setCustomerNo(satTestDriveVO.getCustomerNo());
                satMessAddVO.setSalesConsultantNo(vo.getAccountNo());
                satMessAddVO.setReceiveRoleCode("rolePartnerTestDrive");
                satMessAddVO.setOperaRoleCode(loginInfo.getRoleCode());
                satMessAddVO.setBusinessKey(satTestDriveVO.getDriveId());
                satMessService.newMess(satMessAddVO);
            }
        }
    }
}
